﻿using Core.Info;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text;

namespace Core.Utility.Helper
{
    /// <summary>
    /// 日期/时间助手类
    /// </summary>
    public static class DateTimeHelper
    {
        #region 使用提示
        //DateTime dateTimeNow = DateTime.Now;
        ////本月第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfMonth(dateTimeNow).ToString("yyyy/MM/dd");

        ////本月最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfMonth(dateTimeNow).ToString("yyyy/MM/dd");

        ////上月第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfPrevMonth(dateTimeNow).ToString("yyyy/MM/dd");

        ////上月最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfPrevMonth(dateTimeNow).ToString("yyyy/MM/dd");

        ////下月第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfNextMonth(dateTimeNow).ToString("yyyy/MM/dd");

        ////下月最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfNextMonth(dateTimeNow).ToString("yyyy/MM/dd");

        ////前三个月第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfAssignMonth(dateTimeNow, -3).ToString("yyyy/MM/dd");

        ////前三个月最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfAssignMonth(dateTimeNow, -3).ToString("yyyy/MM/dd");

        ////后三个月第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfAssignMonth(dateTimeNow, 3).ToString("yyyy/MM/dd");

        ////后三个月的最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfAssignMonth(dateTimeNow, 3).ToString("yyyy/MM/dd");

        ////去年当月的第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfAssignMonthAndYear(dateTimeNow, 0, -1).ToString("yyyy/MM/dd");

        ////去年当月的最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfAssignMonthAndYear(dateTimeNow, 0, -1).ToString("yyyy/MM/dd");

        ////当年的第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfYear(dateTimeNow).ToString("yyyy/MM/dd");

        ////当年的最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfYear(dateTimeNow).ToString("yyyy/MM/dd");

        ////去年的第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfPrevYear(dateTimeNow).ToString("yyyy/MM/dd");

        ////去年的最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfPrevYear(dateTimeNow).ToString("yyyy/MM/dd");

        ////明年的第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfNextYear(dateTimeNow).ToString("yyyy/MM/dd");

        ////明年的最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfNextYear(dateTimeNow).ToString("yyyy/MM/dd");

        ////指定N年前的第一天
        //txtDateHelperTest.Text = DateTimeHelper.FirstDayOfAssignYear(dateTimeNow,-2).ToString("yyyy/MM/dd");

        ////指定N年前的最后一天
        //txtDateHelperTest.Text = DateTimeHelper.LastDayOfAssignYear(dateTimeNow, -2).ToString("yyyy/MM/dd");
        #endregion

        /// <summary>
        /// 获取指定时间所在月份的第一天
        /// </summary>
        /// <param name="dateTime">要取得月份第一天的时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfMonth(this DateTime dateTime)
        {
            return FirstDayOfAssignMonth(dateTime, 0);
        }

        /// <summary>
        /// 获取指定时间所在月份的最后一天
        /// </summary>
        /// <param name="dateTime">要取得月份最后一天的时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfMonth(this DateTime dateTime)
        {
            return LastDayOfAssignMonth(dateTime, 0);
        }

        /// <summary>
        /// 取得上个月第一天
        /// </summary>
        /// <param name="dateTime">要取得上个月第一天的当前时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfPrevMonth(this DateTime dateTime)
        {
            return FirstDayOfAssignMonth(dateTime, -1);
        }

        /// <summary>
        /// 取得上个月的最后一天
        /// </summary>
        /// <param name="dateTime">要取得上个月最后一天的当前时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfPrevMonth(this DateTime dateTime)
        {
            return LastDayOfAssignMonth(dateTime, -1);
        }

        /// <summary>
        /// 取得下个月第一天
        /// </summary>
        /// <param name="dateTime">要取得上个月第一天的当前时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfNextMonth(this DateTime dateTime)
        {
            return FirstDayOfAssignMonth(dateTime, 1);
        }

        /// <summary>
        /// 取得下个月的最后一天
        /// </summary>
        /// <param name="dateTime">要取得上个月最后一天的当前时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfNextMonth(this DateTime dateTime)
        {
            return LastDayOfAssignMonth(dateTime, 1);
        }

        /// <summary>
        /// 获取指定时间指定月份前/后的第一天
        /// </summary>
        /// <param name="dateTime">指定的时间</param>
        /// <param name="iAssignMonthAmount">指定的月份 0为当前月份;负数为前N月;正数为后N月</param>
        /// <returns></returns>
        public static DateTime FirstDayOfAssignMonth(this DateTime dateTime, int iAssignMonthAmount)
        {
            return FirstDayOfAssignMonthAndYear(dateTime, iAssignMonthAmount, 0);
        }

        /// <summary>
        /// 获取指定时间指定月份前/后的最后一天
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="iAssignMonthAmount"></param>
        /// <returns></returns>
        public static DateTime LastDayOfAssignMonth(this DateTime dateTime, int iAssignMonthAmount)
        {
            return LastDayOfAssignMonthAndYear(dateTime, iAssignMonthAmount, 0);
        }

        /// <summary>
        /// 获取指定时间 所在季度或前/后N季度 的第一天
        /// </summary>
        /// <param name="dateTime">指定的时间</param>
        /// <param name="iAssignQuarter">指定季度 0为当前季度;负数为前N季度;正数为后N季度</param>
        /// <returns></returns>
        public static DateTime FirstDayOfAssignQuarter(this DateTime dateTime, int iAssignQuarter)
        {
            return dateTime.AddMonths(0 - (dateTime.Month - 1) % 3).AddDays(1 - dateTime.Day).AddMonths(iAssignQuarter * 3);
        }

        /// <summary>
        /// 获取指定时间 所季度或前/后N季度 的最后一天
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="iAssignQuarter">指定季度 0为当前季度;负数为前N季度;正数为后N季度</param>
        /// <returns></returns>
        public static DateTime LastDayOfAssignQuarter(this DateTime dateTime, int iAssignQuarter)
        {
            return dateTime.FirstDayOfAssignQuarter(iAssignQuarter).AddMonths(3).AddDays(-1);
        }

        /// <summary>
        /// 获取指定日期当年的第一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfYear(this DateTime dateTime)
        {
            return FirstDayOfAssignYear(dateTime, 0);
        }

        /// <summary>
        /// 获取指定日期当年的最后一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfYear(this DateTime dateTime)
        {
            return LastDayOfAssignYear(dateTime, 0);
        }

        /// <summary>
        /// 获取指定日期去年的第一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfPrevYear(this DateTime dateTime)
        {
            return FirstDayOfAssignYear(dateTime, -1);
        }

        /// <summary>
        /// 获取指定日期去年的最后一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfPrevYear(this DateTime dateTime)
        {
            return LastDayOfAssignYear(dateTime, -1);
        }

        /// <summary>
        /// 获取指定日期明年的第一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfNextYear(this DateTime dateTime)
        {
            return FirstDayOfAssignYear(dateTime, 1);
        }

        /// <summary>
        /// 获取指定日期明年的最后一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfNextYear(this DateTime dateTime)
        {
            return LastDayOfAssignYear(dateTime, 1);
        }

        /// <summary>
        /// 获取指定日期 指定年份 前/后 的第一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <param name="iAssignYearAmount">指定的年份 0为当前年份;负数为前N年;正数为后N年</param>
        /// <returns></returns>
        public static DateTime FirstDayOfAssignYear(this DateTime dateTime, int iAssignYearAmount)
        {
            return FirstDayOfAssignMonthAndYear(dateTime, 1 - dateTime.Month, iAssignYearAmount);
        }

        /// <summary>
        /// 获取指定日期 指定年份 前/后 的最后一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <param name="iAssignYearAmount">指定的年份 0为当前年份;负数为前N年;正数为后N年</param>
        /// <returns></returns>
        public static DateTime LastDayOfAssignYear(this DateTime dateTime, int iAssignYearAmount)
        {
            return LastDayOfAssignMonthAndYear(dateTime, 12 - dateTime.Month, iAssignYearAmount);
        }

        /// <summary>
        /// 获取指定日期所在星期的第一天
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime FirstDayOfWeek(this DateTime dateTime)
        {
            int weekNow = ((int)dateTime.DayOfWeek);
            weekNow = (weekNow == 0 ? (7 - 1) : (weekNow - 1));
            int dayDiff = (-1) * weekNow;            
            return dateTime.AddDays(dayDiff);
        }

        /// <summary>
        /// 获取指定日期所在周 前/后 N周 的第一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <param name="iAssignWeekAmount">0:当前周,正数：N周后的第一天，父数：N周前的第一天，</param>
        /// <returns></returns>
        public static DateTime FirstDayOfAssignWeek(this DateTime dateTime,int iAssignWeekAmount = 0)
        {
            return FirstDayOfWeek(dateTime).AddDays(7 * iAssignWeekAmount);
        }

        /// <summary>
        /// 获取指定日期所在周 前/后 N周 的最后一天
        /// </summary>
        /// <param name="dateTime">指定时间</param>
        /// <param name="iAssignWeekAmount">0:当前周,正数：N周后的第一天，父数：N周前的最后，</param>
        /// <returns></returns>
        public static DateTime LastDayOfAssignWeek(this DateTime dateTime, int iAssignWeekAmount = 0)
        {
            return LastDayOfWeek(dateTime).AddDays(7 * iAssignWeekAmount);
        }

        /// <summary>
        /// 获取指定日期所在星期的最后一天
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime LastDayOfWeek(this DateTime dateTime)
        {
            int weekNow = ((int)dateTime.DayOfWeek);
            weekNow = (weekNow == 0 ? 7 : weekNow);
            int dayDiff = (7 - weekNow);
            return dateTime.AddDays(dayDiff);
        }

        /// <summary>
        /// 获取参数sourceDateTime在dateTime中对应的周几的日期
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="sourceDateTime"></param>
        /// <returns></returns>
        public static DateTime ThisWeek(this DateTime dateTime, DateTime sourceDateTime)
        {
            int sourceDateTimeWeek = ((int)sourceDateTime.DayOfWeek);
            sourceDateTimeWeek = (sourceDateTimeWeek == 0 ? (7 - 1) : (sourceDateTimeWeek - 1));
            //int dateTimeWeek = ((int)dateTime.DayOfWeek);
            DateTime dateTimeFirstDayOfWeek = FirstDayOfWeek(dateTime);
            return dateTimeFirstDayOfWeek.AddDays(sourceDateTimeWeek);
        }

        /// <summary>
        /// 获取参数sourceDateTime在dateTime中对应的月的所在日
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="sourceDateTime"></param>
        /// <returns></returns>
        public static DateTime ThisMonth(this DateTime dateTime, DateTime sourceDateTime)
        {
            //闰年2月29日
            if (sourceDateTime.Month == 2 
                && DateTime.IsLeapYear(sourceDateTime.Year) 
                && dateTime.Month == 2 
                && sourceDateTime.Day == 29)
            {
                sourceDateTime = sourceDateTime.AddDays(-1);
            }
            return new DateTime(
                dateTime.Year,
                dateTime.Month, 
                sourceDateTime.Day,
                sourceDateTime.Hour,
                sourceDateTime.Minute,
                sourceDateTime.Second,
                sourceDateTime.Millisecond);
        }

        /// <summary>
        /// 获取参数sourceDateTime在dateTime中对应的所在月及所在日
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="sourceDateTime"></param>
        /// <returns></returns>
        public static DateTime ThisYear(this DateTime dateTime, DateTime sourceDateTime)
        {
            //闰年2月29日
            if (sourceDateTime.Month == 2 
                && DateTime.IsLeapYear(sourceDateTime.Year)
                && sourceDateTime.Day == 29)
            {
                sourceDateTime = sourceDateTime.AddDays(-1);
            }
            return new DateTime(
                dateTime.Year,
                sourceDateTime.Month,
                sourceDateTime.Day,
                sourceDateTime.Hour,
                sourceDateTime.Minute,
                sourceDateTime.Second,
                sourceDateTime.Millisecond);
        }

        /// <summary>
        /// 获取指定时间指定 年份 前/后 和 月份前/后的第一天
        /// </summary>
        /// <param name="dateTime">指定的时间</param>
        /// <param name="iAssignMonthAmount">指定的月份 0为当前月份;负数为前N月;正数为后N月</param>
        /// <param name="iAssignYearAmount">指定的年份 0为当前年份;负数为前N年;正数为后N年</param>
        /// <returns></returns>
        public static DateTime FirstDayOfAssignMonthAndYear(this DateTime dateTime, int iAssignMonthAmount, int iAssignYearAmount)
        {
            return dateTime.AddDays(1 - dateTime.Day).AddMonths(iAssignMonthAmount).AddYears(iAssignYearAmount);
        }

        /// <summary>
        /// 获取指定时间指定 年份 前/后 和 月份前/后的最后一天
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="iAssignMonthAmount"></param>
        /// <param name="iAssignYearAmount"></param>
        /// <returns></returns>
        public static DateTime LastDayOfAssignMonthAndYear(this DateTime dateTime, int iAssignMonthAmount, int iAssignYearAmount)
        {
            return dateTime.AddDays(1 - dateTime.Day).AddMonths(1 + iAssignMonthAmount).AddDays(-1).AddYears(iAssignYearAmount);
        }

        /// <summary>
        /// 每日开始时间，即 yyyy-MM-dd 00:00:00.0000
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime DayStartTime(this DateTime dateTime)
        {
            return new DateTime(dateTime.Year,dateTime.Month,dateTime.Day,0,0,0,0);
        }


        /// <summary>
        /// 每日结束时间，即 yyyy-MM-dd 23:59:59.9999
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime DayEndTime(this DateTime dateTime)
        {
            return DayStartTime(dateTime).AddDays(1).AddMilliseconds(-1);
        }

        /// <summary>
        /// R => GMT 格式
        /// </summary>
        public static string[] TimeFormats = new string[] { "R", "yyyyMMddHHmmss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd", "MM-dd", "yyyy MM dd", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyyMMddHHmmss", "yyyyMMddHHmm", "yyyyMMddHH", "yyyyMMdd", "yyyyMM" };

        /// <summary>
        /// 字符串日期时间格式转DateTime
        /// </summary>
        /// <param name="dateTimeString"></param>
        /// <param name="defaultDateTime"></param>
        /// <returns></returns>
        public static DateTime? ToTime(this string dateTimeString,DateTime? defaultDateTime = null)
        {
            if (!string.IsNullOrWhiteSpace(dateTimeString))
            {
                if (DateTime.TryParseExact(dateTimeString, TimeFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var datetime))
                {
                    return datetime;
                }
            }            
            return defaultDateTime;
        }

        /// <summary>
        /// 时间转换，支持 CTS => GMT
        /// </summary>
        /// <param name="dateTimeString"></param>
        /// <returns></returns>
        public static DateTime? ToTimeCanNull(this string dateTimeString)
        {
            var dt = dateTimeString;
            if (dateTimeString?.Contains("CTS") == true || dateTimeString?.Contains("CST") == true)
            {
                var ctsdt = dateTimeString.Split(' ');
                dt = $"{ctsdt[0]}, {ctsdt[2]} {ctsdt[1]} {ctsdt[5]} {ctsdt[3]} GMT";
            }

            if (!string.IsNullOrWhiteSpace(dt))
            {
                if (DateTime.TryParseExact(dt, TimeFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var datetime))
                {
                    return datetime;
                }
            }
            return null;
        }

        /// <summary>
        /// 转换时间为unix时间戳
        /// </summary>
        /// <param name="date">需要传递UTC时间,避免时区误差,例:DataTime.UTCNow</param>
        /// <returns></returns>
        public static long ToUnixTime(this DateTime date)
        {
            return (date.ToUniversalTime().Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000;
        }

        /// <summary>
        /// 转换时间为unix时间戳(13位)
        /// </summary>
        /// <param name="date">需要传递UTC时间,避免时区误差,例:DataTime.UTCNow</param>
        /// <returns></returns>
        public static long ToUnixTime13Bit(this DateTime date)
        {
            return (date.ToUniversalTime().Ticks - new DateTime(1970, 1, 1).Ticks) / 10000;
        }

        /// <summary>
        /// Unix时间戳转换为日期类型
        /// </summary>
        /// <param name="timeStampString">时间戳字符串</param>
        /// <param name="defaultTime">转换失败设置的默认时间，默认值 DateTime.MinValue</param>
        /// <returns></returns>
        public static DateTime ToDateTime(this string timeStampString,DateTime? defaultTime = null)
        {
            DateTime dateTime = defaultTime.GetValueOrDefault(DateTime.MinValue);
            try
            {
                var lTimeStamp = Convert.ToInt64(timeStampString);
                dateTime = ToDateTime(lTimeStamp, defaultTime);
                //dateTime = CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)).AddSeconds(lTimeStamp);
            }
            catch
            {

            }
            return dateTime;
        }

        /// <summary>
        /// Unix时间戳转换为日期类型(兼容13位时间戳)
        /// </summary>
        /// <param name="timeStampLong">时间戳字符串</param>
        /// <param name="defaultTime">转换失败设置的默认时间，默认值 DateTime.MinValue</param>
        /// <returns></returns>
        public static DateTime ToDateTime(this long timeStampLong, DateTime? defaultTime = null)
        {
            DateTime dateTime = defaultTime.GetValueOrDefault(DateTime.MinValue);
            try
            {
                if (timeStampLong.ToString().Length == 13)
                {
                    timeStampLong = timeStampLong * 10000;                    
                }
                else if (timeStampLong.ToString().Length == 10)
                {
                    timeStampLong = timeStampLong * 10000000;
                }
                dateTime = new DateTime(timeStampLong + new DateTime(1970, 1, 1).Ticks).ToLocalTime();
                //dateTime = CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)).AddSeconds(lTimeStamp);
            }
            catch
            {

            }
            return dateTime;
        }


        /// <summary>
        /// 返回与指定的 OLE 自动化日期等效的 DateTime
        /// </summary>
        /// <param name="ole"></param>
        /// <param name="defaultDateTime"></param>
        /// <returns></returns>
        public static DateTime? OleDateToDateTime(int ole,DateTime? defaultDateTime = null)
        {
            DateTime? res = defaultDateTime;
            try
            {
                res = DateTime.FromOADate(ole);
            }
            catch
            {

            }
            return res;
        }

        /// <summary>
        /// 将DateTime转为 OLE 自动化日期
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static int? ToOleDate(DateTime? dateTime)
        {
            int? res = null;
            if(dateTime != null)
            {
                res = (int)dateTime.GetValueOrDefault().ToOADate();
            }
            return res;
        }

        /// <summary>
        /// 转年龄及年龄单位列表 (医学计算常用)
        /// </summary>
        /// <param name="brithday">出生日期</param>
        /// <param name="targetday">目标日期</param>
        /// <returns></returns>
        public static Collection<string> ToAgeAndUnitList(DateTime brithday, DateTime targetday)
        {
            Collection<string> res = new Collection<string>()
            {
                "-"
            };

            try
            {
                TimeSpan ts1 = new TimeSpan(brithday.Date.Ticks);
                TimeSpan ts2 = new TimeSpan(AppTime.Now.Date.Ticks);
                if (ts1.Days > ts2.Days)
                {
                    //return "-";
                    return res;
                }
                /*
                * 小于 = 4周的显示为天数，         比如 28天
                4周以上到2周岁的显示为月 比如 23月
                大于2周岁的显示为实足年龄    比如2000年1月1日出生的人，到2015年8月31日为止，他出生后已经度过了十五年零九个月，实足年龄即为十五年零九个月
                */
                string strAge = string.Empty;
                if (brithday == targetday)
                {
                    return new Collection<string>()
                    {
                        "1",
                        "天"
                    };
                }
                int beginInt = ToOleDate(targetday) ?? 0;
                int endInt = ToOleDate(brithday) ?? 0;
                //小于等于28天的情况
                if (endInt >= (beginInt - 28))
                {
                    var days = beginInt - endInt;
                    //return string.Format("{0}天", (days == 0 ? 1 : days).ToString());
                    return new Collection<string>()
                    {
                        (days == 0 ? 1 : days).ToString(),
                        "天"
                    };
                }
                //大于28天，小于一个月显示一个月
                if (endInt <= (beginInt - 28) && brithday.Date > targetday.AddMonths(-1).Date)
                {
                    //return "1月";
                    return new Collection<string>()
                    {
                        "1",
                        "月"
                    };
                }
                //大于等于一个月，小于2年
                if (brithday.Date <= targetday.AddMonths(-1).Date && brithday.Date > targetday.AddYears(-2).Date)
                {
                    int months = 1;
                    while (brithday.AddMonths(months).Date <= targetday.Date)
                    {
                        months++;
                    }
                    months--;
                    //return string.Format("{0}月", months);
                    return new Collection<string>()
                    {
                        months.ToString(),
                        "月"
                    };
                }
                //大于2年的小于6年
                if (brithday.Date <= targetday.AddYears(-2).Date && brithday.Date > targetday.AddYears(-6).Date)
                {
                    int years = 1;
                    while (brithday.AddYears(years).Date <= targetday.Date)
                    {
                        years++;
                    }
                    years--;
                    //计算月份
                    int months = 0;
                    DateTime jsDateTime = brithday.AddYears(years);
                    while (jsDateTime.AddMonths(months).Date <= (targetday.AddDays(-1).Date))
                    {
                        months++;
                    }
                    //strAge = months > 0 ? string.Format("{0}岁{1}月", years, months) : string.Format("{0}岁", years);
                    res = new Collection<string>()
                    {
                        years.ToString(),
                        "岁",
                    };
                    if (months > 0)
                    {
                        res.Add(months.ToString());
                        res.Add("月");
                    }

                    return res;
                }
                //大于6岁
                if (brithday.Date <= targetday.AddYears(-6).Date)
                {
                    int years = 1;
                    while (brithday.AddYears(years).Date <= targetday.Date)
                    {
                        years++;
                    }
                    years--;
                    strAge = string.Format("{0}岁", years);
                    return new Collection<string>()
                    {
                        years.ToString(),
                        "岁"
                    };
                }

                return res;
                //return strAge;
            }
            catch (Exception ex)
            {
                //return "-";
                return res;
            }
        }
        
        /// <summary>
        /// 通过出生日期计算年龄，单位(岁)，不足日，则结果-1
        /// </summary>
        /// <param name="birthday">出生日期</param>
        /// <param name="targetday">目标日期，为null使用当日</param>
        /// <returns></returns>
        public static int GetAgeByBirthday(DateTime birthday, DateTime? targetday = null)
        {
            DateTime now = AppTime.Now;
            if(targetday != null)
            {
                now = targetday.Value;
            }            
            int age = now.Year - birthday.Year;
            if (now.Month < birthday.Month || (now.Month == birthday.Month && now.Day < birthday.Day))
            {
                age--;
            }
            return age < 0 ? 0 : age;
        }

    }
}
